(function() {

    var
    $u = juliet.using({
        validationResult : 'juliet.validation.validationResult',
        validationEvent : 'juliet.validation.validationEvent',
        validator : 'juliet.validation.validator'
    }),
    ve = $u('validationEvent'),
    vr = $u('validationResult');

    /**
     * Custom validator
     */
    var CustomClass = function() {

        this.validate = function() {
            if (((this.validationEvents & ve.KEYUP) == ve.KEYUP)
                && !this.chain.fieldValueHelper.fieldValueModified
                && (this.result != vr.IN_PROGRESS)
                && (this.result != vr.UNKNOWN)) return;

            this.result = vr.IN_PROGRESS;

            this.metadata.options.validateCallback.call(
                this.metadata.options.context,
                this.chain.fieldValueHelper.fieldValue, this.metadata.options, this
            );
        };

        this.cancelValidate = function() {
            if (this.result != vr.IN_PROGRESS) return;

            var cancelCallback = this.metadata.options.cancelCallback;
            if (cancelCallback) cancelCallback.call(this.metadata.options.context);
        };

        this.getError = function() {
            return this.base.getError.call(this, 'custom');
        };

    };

    $u('validator').addValidator('Custom', CustomClass);

})();
